﻿using Sidvall.IO;
using System;
using System.Threading.Tasks;
using Windows.Media.Capture;

namespace Sidvall.Devices.Uwp
{
    public class Camera : ICamera
    {
        #region Public Members

        #region CaptureFileAsync

        public async Task<IStorageFile> CaptureFileAsync(CameraSettings settings)
        {
            var captureUI = new CameraCaptureUI();
            if ((settings.CaptureMode == CaptureMode.Photo) || ((settings.CaptureMode == CaptureMode.PhotoOrVideo)))
            {
                if (settings.PhotoSettings != null)
                {
                    captureUI.PhotoSettings.AllowCropping = settings.PhotoSettings.AllowCropping;
                    captureUI.PhotoSettings.Format = GetFormat(settings.PhotoSettings.Format);
                    captureUI.PhotoSettings.MaxResolution = GetResolution(settings.PhotoSettings.MaxResolution);
                }
            }
            if ((settings.CaptureMode == CaptureMode.Video) || ((settings.CaptureMode == CaptureMode.PhotoOrVideo)))
            {
                if (settings.VideoSettings != null)
                {
                    captureUI.VideoSettings.AllowTrimming = settings.VideoSettings.AllowTrimming;
                    captureUI.VideoSettings.Format = GetFormat(settings.VideoSettings.Format);
                    captureUI.VideoSettings.MaxResolution = GetResolution(settings.VideoSettings.MaxResolution);
                    captureUI.VideoSettings.MaxDurationInSeconds = settings.VideoSettings.MaxDurationInSeconds;
                }
            }
            var storageFile = await captureUI.CaptureFileAsync(GetCaptureMode(settings.CaptureMode));
            if (storageFile == null)
                return null;
            return new StorageFile(storageFile);
        }

        #endregion
        #region ToString

        public override string ToString()
        {
            return "Camera - UWP";
        }

        #endregion

        #endregion
        #region Private Members

        #region GetCaptureMode

        private CameraCaptureUIMode GetCaptureMode(CaptureMode captureMode)
        {
            switch (captureMode)
            {
                case CaptureMode.PhotoOrVideo:
                    return CameraCaptureUIMode.PhotoOrVideo;
                case CaptureMode.Photo:
                    return CameraCaptureUIMode.Photo;
                case CaptureMode.Video:
                    return CameraCaptureUIMode.Video;
                default:
                    throw new System.ArgumentException(nameof(captureMode));
            }
        }

        #endregion
        #region GetFormat

        private CameraCaptureUIPhotoFormat GetFormat(PhotoFormat format)
        {
            switch (format)
            {
                case PhotoFormat.Jpeg:
                    return CameraCaptureUIPhotoFormat.Jpeg;
                case PhotoFormat.Png:
                    return CameraCaptureUIPhotoFormat.Png;
                case PhotoFormat.JpegXR:
                    return CameraCaptureUIPhotoFormat.JpegXR;
                default:
                    throw new System.ArgumentException(nameof(format));
            }
        }
        private CameraCaptureUIVideoFormat GetFormat(VideoFormat format)
        {
            switch (format)
            {
                case VideoFormat.Mp4:
                    return CameraCaptureUIVideoFormat.Mp4;
                case VideoFormat.Wmv:
                    return CameraCaptureUIVideoFormat.Wmv;
                default:
                    throw new System.ArgumentException(nameof(format));
            }
        }

        #endregion
        #region GetResolution

        private CameraCaptureUIMaxPhotoResolution GetResolution(PhotoResolution resolution)
        {
            switch (resolution)
            {
                case PhotoResolution.HighestAvailable:
                    return CameraCaptureUIMaxPhotoResolution.HighestAvailable;
                case PhotoResolution.VerySmallQvga:
                    return CameraCaptureUIMaxPhotoResolution.VerySmallQvga;
                case PhotoResolution.SmallVga:
                    return CameraCaptureUIMaxPhotoResolution.SmallVga;
                case PhotoResolution.MediumXga:
                    return CameraCaptureUIMaxPhotoResolution.MediumXga;
                case PhotoResolution.Large3M:
                    return CameraCaptureUIMaxPhotoResolution.Large3M;
                case PhotoResolution.VeryLarge5M:
                    return CameraCaptureUIMaxPhotoResolution.VeryLarge5M;
                default:
                    throw new System.ArgumentException(nameof(resolution));
            }
        }
        private CameraCaptureUIMaxVideoResolution GetResolution(VideoResolution resolution)
        {
            switch (resolution)
            {
                case VideoResolution.HighestAvailable:
                    return CameraCaptureUIMaxVideoResolution.HighestAvailable;
                case VideoResolution.LowDefinition:
                    return CameraCaptureUIMaxVideoResolution.LowDefinition;
                case VideoResolution.StandardDefinition:
                    return CameraCaptureUIMaxVideoResolution.StandardDefinition;
                case VideoResolution.HighDefinition:
                    return CameraCaptureUIMaxVideoResolution.HighDefinition;
                default:
                    throw new System.ArgumentException(nameof(resolution));
            }
        }

        #endregion

        #endregion
    }
}
